//
//  THWKWebViewBridge.swift
//  YYProject
//
//  Created by 陆文宇 on 2017/9/2.
//  Copyright © 2017年 陆文宇. All rights reserved.
//

import WebKit

class THBridgeAction {
    
    var isValid: Bool {
        return !method.isEmpty
    }
    
    var port: String
    var method: String
    var data: [String: Any]
    
    init(port: String, method: String, data: [String: Any]) {
        self.port = port
        self.method = method
        self.data = data
    }
    
    convenience init?(body: NSDictionary) {
        if let port = body["port"] as? String,
            let method = body["method"] as? String,
            let data = body["data"] as? [String: Any] {
            
            self.init(port: port, method: method, data: data)
        } else {
            return nil
        }
    }
    
}

class THBridgeActionResult {
    
    var isValid: Bool {
        return port != ""
    }
    
    var port: String
    var status = true
    var result: Any?
    
    init(port: String, status: Bool, result: Any?) {
        self.port = port
        self.status = status
        self.result = result
    }
    
}

class THWKWebViewBridge: NSObject, WKScriptMessageHandler {
    
    let THBridgeName = "THIOSBridge"
    
    private var handlerMapper: [String: ((YYWebController, [String: Any], String) -> Void)] = [:]
    private(set) unowned var webView: WKWebView
    private(set) unowned var controller: YYWebController
    
    init(webView: WKWebView, controller: YYWebController) {
        self.webView = webView
        self.controller = controller
        super.init()
        
        webView.configuration.userContentController.add(self, name: THBridgeName)
    }
    
    func registerHandler(_ method: String, callback: @escaping ((YYWebController, [String: Any], String) -> Void)) {
        handlerMapper[method] = callback
    }
    
    func handleAction(_ action: THBridgeAction) {
        if let handler = handlerMapper[action.method] {
            handler(controller, action.data, action.port)
        } else {
            yy_Log("未注册方法: " + action.method)
            callBack(result: THBridgeActionResult(port: action.port, status: false, result: "调用失败"))
        }
    }
    
    func callBack(result: THBridgeActionResult) {
        guard result.isValid else {
            return
        }
        
        let data = (try? JSONSerialization.yy_string(withJSONObject: (result.result == nil) ? [] : [result.result!])) ?? ""
        if result.status {
            webView.evaluateJavaScript("H5App.onSuccess('\(result.port)','\(data)')", completionHandler: nil)
        } else {
            webView.evaluateJavaScript("H5App.onFailure('\(result.port)','\(data)')", completionHandler: nil)
        }
    }
    
    func nativeCallJs(method: String, params: [String: Any]) {
        let data = (try? JSONSerialization.yy_string(withJSONObject: params)) ?? ""
        webView.evaluateJavaScript("H5NativeApp.call('\(method)',\(data))", completionHandler: nil)
    }
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard message.name == THBridgeName else {
            return
        }
        
        if let body = message.body as? NSDictionary,
            let action = THBridgeAction(body: body) {
            handleAction(action)
        }
    }
    
}
